﻿using SqlSugar;
using System.Reflection;
using Zhaoxi.SqlSugar.Common;
using Zhaoxi.SqlSugar.Models;

namespace Zhaoxi.SqlSugarAdvanced
{
    public class MigrationInfo
    {
        #region 变量属性
        /// <summary>
        /// 生成的实体类存放路径
        /// </summary>
        static string ClassPath = "D:\\zhy\\代码测试\\SqlSugar数据库demo\\Zhaoxi.DotNet.Demo\\models";// 生成的实体类存放路径
        #endregion

        #region DbFirst-快速把数据库表生成实体类
        /// <summary>
        /// DbFirst-快速把数据库表生成实体类
        /// </summary>
        public static void DbFirstShow()
        {
            //连接配置对象 - 这个配置要比EFCore简单很多
            ConnectionConfig connectionConfig = new ConnectionConfig()
            {
                ConnectionString = CustomConnectionConfig.ConnectionString001, // 数据库连接字符串
                IsAutoCloseConnection = true, // 是否自动关闭连接
                DbType = DbType.SqlServer // 数据库类型
            };

            //SqlSugarClient：链接数据库的对象 
            using (SqlSugarClient db = new SqlSugarClient(connectionConfig))
            {
                #region 生成数据库对应的实体类-可设置类命名空间
                //参数1：路径  参数2：命名空间
                //IsCreateAttribute 代表生成SqlSugar特性
                {
                    // 生成实体类，
                    db.DbFirst.IsCreateAttribute() //生成带有SqlSugar特性的实体
                        .CreateClassFile(ClassPath, "Models"); // 生成的实体类存放路径和命名空间
                }
                #endregion

                #region 生成实体类-格式化文件名-可设置文件名大小写
                //格式化文件名
                {
                    db.DbFirst.FormatFileName(x => x.ToLower()) //文件名转换为小写
                        .CreateClassFile(ClassPath); // 文件名转换为小写
                }
                #endregion

                #region 生成实体类 - 强制可以空类型加上？
                //强制可以空类型加上？
                {
                    db.DbFirst.StringNullable() //强制可以空类型加上？
                        .CreateClassFile(ClassPath); // 生成的实体类存放路径
                }
                #endregion

                #region 生成实体类 - 根据筛选条件
                //生成实体并且带有筛选
                {
                    db.DbFirst.Where("Student") //根据表名筛选
                        .CreateClassFile(ClassPath, "Models");

                    db.DbFirst.Where(it => it.ToLower().StartsWith("snow")) //根据表名筛选
                        .CreateClassFile(ClassPath, "Models");

                    db.DbFirst.Where(it => it.ToLower().StartsWith("view")) //根据表名筛选
                        .CreateClassFile(ClassPath, "Models");
                }
                #endregion

                #region 生成带有特性的实体类
                //生成带有SqlSugar特性的实体
                {
                    db.DbFirst.IsCreateAttribute() //生成带有SqlSugar特性的实体
                        .CreateClassFile(ClassPath, "Models");
                }
                #endregion

                #region 生成实体带有默认值 - 需要数据字段带有默认值
                //生成实体带有默认值
                {
                    db.DbFirst.IsCreateDefaultValue() //生成带有默认值的实体
                        .CreateClassFile(ClassPath, "Demo.Models");
                }
                #endregion

                #region 生成实体类 - 自定义格式化
                //自定义格式化功能
                {
                    db.DbFirst     //类 
                     .SettingClassTemplate(old => { return old;/*修改old值替换*/ }) //生成类模板
                     .SettingConstructorTemplate(old => { return old;/*修改old值替换*/ }) //构造函数
                     .SettingNamespaceTemplate(old => // 命名空间引用
                     {
                         return old + "\r\nusing SqlSugar;"; //类中添加引用SqlSugar
                     })
                     .SettingPropertyDescriptionTemplate(old => { return old;/*修改old值替换*/})  //属性备注
                     .SettingPropertyTemplate((columns, temp, type) =>   //属性:新重载 完全自定义用配置
                    {
                        var columnattribute = "\r\n           [SugarColumn({0})]"; // 自定义特性模板
                        List<string> attributes = new List<string>();
                        if (columns.IsPrimarykey) // 是否主键
                            attributes.Add("IsPrimaryKey=true"); // 主键
                        if (columns.IsIdentity) // 是否自增
                            attributes.Add("IsIdentity=true"); // 自增
                        if (attributes.Count == 0) // 如果没有特性
                        {
                            columnattribute = ""; // 清空特性模板
                        }
                        // 拼接自定义特性
                        return temp.Replace("{PropertyType}", type) // 替换属性类型
                                    .Replace("{PropertyName}", columns.DbColumnName) // 替换属性名称
                                    .Replace("{SugarColumn}", string.Format(columnattribute, string.Join(",", attributes))); // 替换特性
                    })
                     .CreateClassFile(ClassPath); // 生成的实体类存放路径
                }
                #endregion
            }
        }
        #endregion

        #region CodeFirst - 快速把实体类生成数据库表
        /// <summary>
        /// CodeFirst - 快速把实体类生成数据库表
        /// </summary>
        public static void CodeFirstShow()
        {
            //连接配置对象 - 这个配置要比EFCore简单很多
            ConnectionConfig connectionConfig = new ConnectionConfig() // 连接配置对象
            {
                ConnectionString = CustomConnectionConfig.ConnectionString002,
                IsAutoCloseConnection = true, // 自动关闭连接
                DbType = DbType.SqlServer // 数据库类型
            };
            using (SqlSugarClient db = new SqlSugarClient(connectionConfig)) // SqlSugarClient：链接数据库的对象
            {
                #region CodeFirst-创建一个空的数据库
                //如果不存在创建数据库存在不会重复创建 
                {
                    db.DbMaintenance.CreateDatabase(); // 注意 ：Oracle和个别国产库需不支持该方法，需要手动建库  
                }
                #endregion

                #region 创建指定实体类的表
                //创建表根据实体类CodeFirstTable1     
                {
                    db.CodeFirst.InitTables(typeof(CodeFirstTable1));//这样一个表就能成功创建了
                }
                #endregion

                #region 设置默认的字符串长度
                //创建单个表 
                {
                    db.CodeFirst.SetStringDefaultLength(200) //设置默认的字符串长度为200
                        .InitTables(typeof(CodeFirstTable1));//这样一个表就能成功创建了
                }
                #endregion

                #region 一次可以创建多个表
                //手动建多个表 
                {
                    db.CodeFirst
                        .SetStringDefaultLength(200) //设置默认的字符串长度为200
                        .InitTables(typeof(CodeFirstTable1), typeof(CodeFirstTable2)); //这样多个表就能成功创建了
                }
                #endregion

                #region 通过加载models.dll批量创建表
                //批量创建表
                //语法1：
                {
                    Type[] types = Assembly // 加载程序集
                       .LoadFrom("Zhaoxi.SqlSugar.Models.dll")//如果 .dll报错，可以换成 xxx.exe 有些生成的是exe 
                       .GetTypes().Where(it => it.FullName.Contains("CodeFirst")) //命名空间过滤，当然你也可以写其他条件过滤
                       .ToArray();//断点调试一下是不是需要的Type，不是需要的在进行过滤 



                    //判断如果数据库存在这个表，就删除表
                    foreach (Type type in types) // 遍历所有类型
                    {
                        if (db.DbMaintenance.IsAnyTable(type.Name, false)) //判断表是否存在
                        {
                            db.DbMaintenance.DropTable(type.Name); // 如果存在就删除表
                        }
                    } 

                    //然后创建
                    db.CodeFirst.SetStringDefaultLength(200) //设置默认的字符串长度为200
                        .InitTables(types);//根据types创建表
                }
                #endregion

                #region 通过获取当前程序集的所有类型批量创建表
                //语法2：                
                {
                    Type[] types = typeof(CodeFirstTable1).Assembly.GetTypes() //获取当前程序集的所有类型
                   .Where(it => it.FullName.Contains("CodeFirst"))//命名空间过滤，当然你也可以写其他条件过滤
                   .ToArray(); // 断点调试一下是不是需要的Type，不是需要的在进行过滤

                    //判断如果数据库存在这个表，就删除表
                    foreach (Type type in types)
                    {
                        if (db.DbMaintenance.IsAnyTable(type.Name, false)) //判断表是否存在
                        {
                            db.DbMaintenance.DropTable(type.Name); // 如果存在就删除表
                        }
                    }

                    db.CodeFirst.SetStringDefaultLength(200) //设置默认的字符串长度为200
                        .InitTables(types);//根据types创建表
                }
                #endregion

                #region 对指定实体类表进行重命名
                //动态设置表名
                {
                    db.CodeFirst.As<UnituLong>("UnituLong0011") //重命名表名为UnituLong0011
                        .InitTables<UnituLong>(); //这样一个表就能成功创建了
                }
                #endregion
            }
        }
        #endregion

        #region CodeFirst - 创建表的各种索引
        /// <summary>
        /// CodeFirst - 表创表的各种索引
        /// </summary>
        public static void CodeFirstIndexShow()
        {
            ConnectionConfig connectionConfig = new ConnectionConfig()
            {
                ConnectionString = "Data Source=PC-202206030027;Initial Catalog=ZhaoxiSqlSugarDb_NewInfo;Integrated Security=True",
                IsAutoCloseConnection = true, // 是否自动关闭连接
                DbType = DbType.SqlServer // 数据库类型
            };
            using (SqlSugarClient db = new SqlSugarClient(connectionConfig)) 
            {
                //创建表根据实体类CodeFirstTable3     
                {
                    db.CodeFirst.InitTables(typeof(CodeFirstTable3));//这样一个表就能成功创建了
                }
            }
        }
        #endregion
    }
}
